#include "SemanticNodeConstructor.h"

#include "SemanticNodeMethodBody.h"
#include "../errors_warnings.h"

SemanticNodeConstructor::SemanticNodeConstructor (SyntaxTreeNode *syntaxNode, SemanticNode *parent) : SemanticNode(parent) {

	parseMods(syntaxNode->Nodes->GetData(0));
	name = CompilerData->Units->GetLexicUnitString(&CompilerData->Units->GetLexicUnit(syntaxNode->Nodes->GetData(1)->LexUnitID));
	arguments = OurSemanticAnalyzer::analyzeNodeArgument(syntaxNode->Nodes->GetData(3), parent);
	if (syntaxNode->Nodes->GetData(5)->Production == Gr_ConstrInherit__epsilon)
		inheritCall = NULL;
	else
		inheritCall = new SemanticNodeMethodCall(syntaxNode->Nodes->GetData(5), this);
	body = new SemanticNodeMethodBody(syntaxNode->Nodes->GetData(6), this);

}

void SemanticNodeConstructor::parseMods (SyntaxTreeNode* modsNode) {
	modPrivate = false; modProtected = false; modPublic = false;
	for (int i = 0; i < modsNode->Nodes->GetCount(); ++i) {
		switch (modsNode->Nodes->GetData(i)->Production) {
		case Gr_MethodMod__private:
			if (modPrivate || modPublic || modProtected) {
				LexicUnit lu = CompilerData->Units->GetLexicUnit(modsNode->Nodes->GetData(i)->Nodes->GetData(0)->LexUnitID);
				CompilerData->ErrorWarningReport->ReportError(&lu, ERR_SEM_MULTIPLE_ACCESS_MODIFIERS);
				break;
			}
			modPrivate = true;
			break;
		case Gr_MethodMod__protected:
			if (modPrivate || modPublic || modProtected) {
				LexicUnit lu = CompilerData->Units->GetLexicUnit(modsNode->Nodes->GetData(i)->Nodes->GetData(0)->LexUnitID);
				CompilerData->ErrorWarningReport->ReportError(&lu, ERR_SEM_MULTIPLE_ACCESS_MODIFIERS);
				break;
			}
			modProtected = true;
			break;
		case Gr_MethodMod__public:
			if (modPrivate || modPublic || modProtected) {
				LexicUnit lu = CompilerData->Units->GetLexicUnit(modsNode->Nodes->GetData(i)->Nodes->GetData(0)->LexUnitID);
				CompilerData->ErrorWarningReport->ReportError(&lu, ERR_SEM_MULTIPLE_ACCESS_MODIFIERS);
				break;
			}
			modPublic = true;
			break;
		default:
			// ako je sintaksa dobro napravljena ovo se ne bi smjelo dogodit
			break;
		}
	}
	if (!modProtected && !modPublic) modPrivate = true;
}



std::string SemanticNodeConstructor::toDebugString(int tab) {
	std::ostringstream ss;
	for (int i = 0; i < tab; i++) ss << DEBUG_STRING_RAZMAK;

	if (modPrivate) ss << "private ";
	if (modProtected) ss << "protected ";
	if (modPublic) ss << "public ";

	ss << name << " ";

	ss << "(" << std::endl;
	for (std::vector<SemanticNodeExpression*>::iterator i = arguments.begin(); i != arguments.end(); ++i) {
		ss << (*i)->toDebugString(tab+1);
	}
	for (int i = 0; i < tab; i++) ss << DEBUG_STRING_RAZMAK;
	ss << ")" << std::endl;
	if (inheritCall) ss << inheritCall->toDebugString(tab+1);
	ss << body->toDebugString(tab+1);

	//ss << std::endl;
	return ss.str();
}




